<?php
namespace Core;
use Core\Db\Mysql;

/**
 *
 CREATE TABLE swoole_session(
id CHAR(32) primary key COMMENT 'session id',
data blob COMMENT  'session的数据',
utime int unsigned comment '更新时间'
)DEFAULT charset=utf8 comment 'session表';
 * Class Session
 */
class  Session extends Base {
    /**
     * @var Mysql
     */
    protected $db;
    public $opened = false;
    public $data = [];
    public $id;
    public $name = 'ssid';
    public $expire = 36000;
    public $path = '/';
    public $table = '';
    public $domain = '';
    public function mkid() {
        return uniqid(bin2hex(random_bytes(3)),true);
    }
    public function start($key='',$id='') {
        if($this->opened) {
            return;
        }
        if(!$key) {
            $key = Once::$APP_PARAM['session.key'];
        }
        if(!$this->table) {
            $this->table = Once::$APP_PARAM['session.table'];
        }
        if(!$key || !$this->table) {
            throw new \Exception('Session key or table can`t be null');
        }
        $this->opened = true;
        $this->db = Mysql::Instance($key);
        if(!$id && isset(Once::$REQUEST->cookie[$this->name])) {
            $id = Once::$REQUEST->cookie[$this->name];
        }
        if(!$id) {
            $this->id = $this->mkid();
            $this->data = [];
        }else {
            $this->id = $id;
            $data = $this->db->fetchRow('select data from '.$this->table.' WHERE id=:id',[':id'=>$id]);
            if($data) {
                $this->data = \swoole_serialize::unpack($data['data']);
                if(!is_array($this->data)) {
                    $this->data = [];
                }
            }else {
                $this->data = [];
            }
        }
        Once::$RESPONSE->cookie($this->name,$this->id,time()+$this->expire,$this->path,$this->domain);
    }


    public function free() {
        echo 'free session';
            if($this->opened) {
                var_export($this->data);
                if(!empty($this->data)) {
                    $this->db->query('insert into '.$this->table.' (id,data,utime) VALUES (:id,:data,:utime) on duplicate key UPDATE data=VALUES(data),utime=VALUES(utime)',[
                        ':id' => $this->id,
                        ':data' => \swoole_serialize::pack($this->data,0),
                        ':utime' => time()
                    ]);
                }
                $this->data = [];
                $this->id = null;
                $this->table = null;
                $this->opened = false;
            }
    }

    public function set($key,$val) {
        $this->start();
        $this->data[$key] = $val;
    }

    public function get($key,$default=null) {
        $this->start();
        if(isset($this->data[$key])) {
            return $this->data[$key];
        }
        return $default;
    }

    public function delete($key) {
        $this->start();
        unset($this->data[$key]);
    }


    public function truncate() {
        if($this->opened) {
            $this->db->query('delete from '.$this->table.' where id=:id',[
                ':id' => $this->id,
            ]);
            $this->data = [];
            $this->id = null;
            $this->table = null;
            $this->opened = false;
        }
    }
}